#pragma once
#include "TestHarness.h"
#include "CsvFileReader.h"

#include <cmath>
#include <string>
#include <iostream>

namespace
{
    const double epsilon = 0.00001;
    bool doubleEquals(double left, double right ) {
      return (fabs(left - right) < epsilon);
    }

    bool doubleLess(double left, double right, bool orequal = false) {
      if (fabs(left - right) < epsilon) {
        return (orequal);
      }
      return (left < right);
    }

    bool doubleGreater(double left, double right, bool orequal = false) {
      if (fabs(left - right) < epsilon) {
        return (orequal);
      }
      return (left > right);
    }

    const std::string csvFilePath = "..\\TestData\\CsvFileReader\\AAWarrantSearch_201109251249_few_record.csv" ;
}

//
//TEST( CsvFileReader, Test )
//{
//    try
//    {
//        CsvFileReader subject( csvFilePath );
//
//        while( subject.ReadRow() )
//        {
//            std::cout << subject.GetStringData( "ID" )  <<", "
//                      << subject.GetStringData( "Nominal " )  <<", "
//                      << subject.GetStringData( "Chg" )  <<", "
//                      << subject.GetStringData( "Volume" )  <<", "
//                      << subject.GetStringData( "Call/Put" )  <<", "
//                      << subject.GetStringData( "Pre(%)" )  <<", "
//                      << subject.GetStringData( "Eff.Gearing(x)" )  <<", "
//                      << subject.GetStringData( "Strike" )  <<", "
//                      << subject.GetStringData( "Conv.price" )  <<", "
//                      << subject.GetStringData( "Outstanding qty(%)" )  <<", "
//                      << subject.GetStringData( "Issuer" )  <<", "
//            <<std::endl;
//        }
//    }
//    catch( std::invalid_argument e )
//    {
//        std::cout <<std::endl << e.what() <<std::endl ;
//        CHECK(false);
//    }
//    catch( std::runtime_error e )
//    {
//        std::cout <<std::endl << e.what() <<std::endl ;
//        CHECK(false);
//    }
//    catch( ... )
//    {
//        std::cout <<std::endl << "unknown exception thrown"<<std::endl ;
//        CHECK(false);
//    }
//}

TEST( CsvFileReader, GetString )
{
    try
    {
        CsvFileReader subject( "|", csvFilePath );

        CHECK( subject.ReadRow() );
        CHECK( subject.GetStringData( "ID" ) == "14547.HK" );
        CHECK( subject.GetStringData( "Nominal " ) == "0.139" );
        CHECK( subject.GetStringData( "Outstanding qty(%)" ) == "0" );
        CHECK( subject.GetStringData( "Issuer" ) == "SC" );

        CHECK( subject.ReadRow() );
        CHECK( subject.GetStringData( "ID" ) == "24534.HK" );
        CHECK( subject.GetStringData( "Nominal " ) == "0.025" );
        CHECK( subject.GetStringData( "Outstanding qty(%)" ) == "47.77" );
        CHECK( subject.GetStringData( "Issuer" ) == "JP" );

        CHECK( subject.ReadRow() );
        CHECK( subject.GetStringData( "ID" ) == "11043.HK" );
        CHECK( subject.GetStringData( "Nominal " ) == "0.01" );
        CHECK( subject.GetStringData( "Outstanding qty(%)" ) == "11.09" );
        CHECK( subject.GetStringData( "Issuer " ) == "SC" );

        CHECK( !subject.ReadRow() );
    }
    catch( std::invalid_argument e )
    {
        std::cout <<std::endl << e.what() <<std::endl ;
        CHECK(false);
    }
    catch( std::runtime_error e )
    {
        std::cout <<std::endl << e.what() <<std::endl ;
        CHECK(false);
    }
    catch( ... )
    {
        std::cout <<std::endl << "unknown exception thrown"<<std::endl ;
        CHECK(false);
    }
}

TEST( CsvFileReader, GetDouble )
{
    try
    {
        CsvFileReader subject( "|", csvFilePath );

        CHECK( subject.ReadRow() );
        CHECK( doubleEquals( subject.GetDoubleData( "Strike" ), 63.88 ) );
        CHECK( doubleEquals( subject.GetDoubleData( "Nominal " ), 0.139 ) );
        CHECK( doubleEquals( subject.GetDoubleData( "Outstanding qty(%)" ), 0 ) );
        CHECK( doubleEquals( subject.GetDoubleData( "Conv.price" ), 6.9 ) );

        CHECK( subject.ReadRow() );
        CHECK( doubleEquals( subject.GetDoubleData( "Strike" ), 83.88 ) );
        CHECK( doubleEquals( subject.GetDoubleData( "Nominal " ), 0.025 ) );
        CHECK( doubleEquals( subject.GetDoubleData( "Outstanding qty(%)" ), 47.77 ) );
        CHECK( doubleEquals( subject.GetDoubleData( "Conv.price" ), 86.4 ) );

        CHECK( subject.ReadRow() );
        CHECK( doubleEquals( subject.GetDoubleData( "Strike" ), 88.88 ) );
        CHECK( doubleEquals( subject.GetDoubleData( "Nominal " ), 0.01 ) );
        CHECK( doubleEquals( subject.GetDoubleData( "Outstanding qty(%)" ), 11.09 ) );
        CHECK( doubleEquals( subject.GetDoubleData( "Conv.price " ), 89 ) );

        CHECK( !subject.ReadRow() );
    }
    catch( std::invalid_argument e )
    {
        std::cout <<std::endl << e.what() <<std::endl ;
        CHECK(false);
    }
    catch( std::runtime_error e )
    {
        std::cout <<std::endl << e.what() <<std::endl ;
        CHECK(false);
    }
    catch( ... )
    {
        std::cout <<std::endl << "unknown exception thrown"<<std::endl ;
        CHECK(false);
    }
}